package graphics;

import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.Point;
import java.awt.Polygon;

import controller.Constants;

/**
 * A star
 * 
 * @author Jie Zhao(288654)
 * 
 */
public class Star extends RectBoundedShape {
	private Point[] points = new Point[5];
	private Point[] innerPoints = new Point[5];

	@Override
	public String toString() {
		StringBuffer sb = new StringBuffer();
		sb.append("star:");
		sb.append(getLineColor().getRGB()+":");
		sb.append((isFilled()?"1":"0") + ":");
		sb.append(getFilledColor().getRGB()+":");
		sb.append(getStroke().getLineWidth()+":");
		sb.append(getStartPoint().x+","+getStartPoint().y+":");
		sb.append(getEndPoint().x+","+getEndPoint().y);
		return sb.toString();
	}

	@Override
	public void fromString(String str) {
		try{
		String[] data = str.split(":");
		if(!data[0].equals("star"))return;
		setLineColor(new Color(Integer.parseInt(data[1])));
		setFilled(data[2].equals("1"));
		setFilledColor(new Color(Integer.parseInt(data[3])));
		setStroke(new BasicStroke(Float.parseFloat(data[4]),BasicStroke.CAP_ROUND,BasicStroke.CAP_ROUND));
		String[] point = data[5].split(",");
		setStartPoint(new Point(Integer.parseInt(point[0]),Integer.parseInt(point[1])));
		point = data[6].split(",");
		setEndPoint(new Point(Integer.parseInt(point[0]),Integer.parseInt(point[1])));
		}catch(Exception e)
		{
			if(Constants.DEBUG)e.printStackTrace();
		}
	}
	public Star() {
		super();
		for (int i = 0; i < points.length; i++) {
			points[i] = new Point();
		}
		for (int i = 0; i < innerPoints.length; i++) {
			innerPoints[i] = new Point();
		}
	}

	@Override
	/**
	 * draw the star
	 */
	public void draw(Graphics g) {
		super.draw(g);
		calculatePoints();

		Graphics2D g2d = (Graphics2D) g;
		g2d.setStroke(getStroke());
		g2d.setColor(getLineColor());

		for (int i = 0; i < points.length; i++) {
			drawLine(g2d, points[i], innerPoints[i % 5]);
			drawLine(g2d, points[i], innerPoints[(i + 1) % 5]);
		}

		if (isFilled()) {
			g2d.setColor(getFilledColor());
			Polygon p = new Polygon();
			for (int i = 0; i < points.length; i++) {
				p.addPoint(innerPoints[i].x, innerPoints[i].y);
				p.addPoint(points[i].x, points[i].y);
			}
			g2d.fillPolygon(p);
		}
	}

	private void calculatePoints() {
		// point 0-4 is deasil orderd.

		double tan36 = Math.tan(36.0 / 180 * Math.PI);
		double tan18 = Math.tan(18.0 / 180 * Math.PI);
		double cos18 = Math.cos((18.0 / 180 * Math.PI));
		double sin36 = Math.sin((36.0 / 180 * Math.PI));
		double cos36 = Math.cos((36.0 / 180 * Math.PI));

		regulate();
		points[0].x = x + width / 2;
		points[0].y = y;

		points[1].x = x + width;
		points[1].y = y + (int) ((width / 2) * tan36);

		points[2].x = points[0].x + (int) (height * tan18);
		points[2].y = y + height;

		points[3].x = points[0].x - (int) (height * tan18);
		points[3].y = points[2].y;

		points[4].x = x;
		points[4].y = points[1].y;

		// inner point start from left-upper corner
		innerPoints[0].x = points[0].x
				- (int) ((points[1].y - points[0].y) * tan18);
		innerPoints[0].y = points[1].y;

		innerPoints[1].x = points[0].x
				+ (int) ((points[1].y - points[0].y) * tan18);
		innerPoints[1].y = points[1].y;

		innerPoints[2].x = (int) (points[1].x - ((points[1].y - points[0].y) / cos18)
				* cos36);
		innerPoints[2].y = (int) (points[1].y + ((points[1].y - points[0].y) / cos18)
				* sin36);

		innerPoints[3].x = points[0].x;
		innerPoints[3].y = (int) (points[1].y + tan36 * width / 2);

		innerPoints[4].x = (int) (points[4].x + ((points[1].y - points[0].y) / cos18)
				* cos36);
		innerPoints[4].y = innerPoints[2].y;
	}

	private void drawLine(Graphics2D g2d, Point a, Point b) {
		g2d.drawLine(a.x, a.y, b.x, b.y);
	}
}
